home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 16 / CU Amiga Magazine's Super CD-ROM 16 (1997-10-16)(EMAP Images)(GB)[!][issue 1997-11].iso / CUCD / Online / HBBS / Source / Node / Node_Main.c < prev    next >
C/C++ Source or Header  |  1997-08-28  |  43KB  |  1,431 lines

  1. /*
  2.  
  3.  
  4.    modify NodeGUI.C so that it has these two lines in the OpenNodeWndWindow()
  5.    function.
  6.  
  7.                 (WA_Left), N_ND->NodeX,
  8.                 (WA_Top), N_ND->NodeY,
  9.  
  10.    and so it has these includes and external definition right after "NodeGUI.H"
  11.  
  12.    #include "/common/types.h"
  13.    #include "/common/defines.h"
  14.    #include "/common/structures.h"
  15.  
  16.    extern struct NodeData *N_ND;
  17.  
  18. */
  19.  
  20. #include <stdio.h>
  21. #include <exec/types.h>
  22. #include <libraries/locale.h>
  23. #include <exec/memory.h>
  24. #include <dos/dosextens.h>
  25. #include <intuition/screens.h>
  26. #include <intuition/intuition.h>
  27. #include <intuition/gadgetclass.h>
  28. #include <libraries/gadtools.h>
  29. #include <diskfont/diskfont.h>
  30. #include <utility/utility.h>
  31. #include <graphics/gfxbase.h>
  32. #include <devices/console.h>
  33. #include <devices/serial.h>
  34. #include <devices/timer.h>
  35. #include <workbench/workbench.h>
  36. #include <graphics/scale.h>
  37. #include <clib/locale_protos.h>
  38. #include <clib/exec_protos.h>
  39. #include <clib/wb_protos.h>
  40. #include <clib/intuition_protos.h>
  41. #include <clib/gadtools_protos.h>
  42. #include <clib/graphics_protos.h>
  43. #include <clib/utility_protos.h>
  44. #include <string.h>
  45. #include <clib/diskfont_protos.h>
  46.  
  47. #include <dos/dos.h>
  48. #include <dos/dostags.h>
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #include <ctype.h>
  52. #include <time.h>
  53.  
  54. #include <libraries/reqtools.h>
  55.  
  56. #include <clib/alib_protos.h>
  57. #include <clib/dos_protos.h>
  58. #include <clib/reqtools_protos.h>
  59.  
  60. #include "NodeGUI.h"
  61.  
  62. #define MAIN
  63.  
  64. struct ReqToolsBase *ReqToolsBase;
  65.  
  66. #ifdef __SASC
  67. int CXBRK(void) { return(0); }
  68. int _CXBRK(void) { return(0); }
  69. void chkabort(void) {}
  70. #endif
  71.  
  72. #include <hbbs/options.h>
  73. #include <hbbs/release.h>
  74.  
  75. #include <hbbs/types.h>
  76. #include <hbbs/errors.h>
  77. #include <hbbs/defines.h>
  78. #include <hbbs/structures.h>
  79. #include <hbbs/strings.h>
  80. #include <hbbs/files.h>
  81. #include <hbbs/ansi_codes.h>
  82.  
  83. #include "Node_Options.h"
  84. //#include "Node_Console_Protos.h"
  85. #include "Node_Serial_Protos.h"
  86. #include "Node_Input_Protos.h"
  87. #include "Node_Misc_Protos.h"
  88.  
  89. #include <HBBS/Hbbscommon_protos.h>
  90. #ifdef __SASC
  91. #include <HBBS/hbbscommon_pragmas_sas.h>
  92. #else
  93. #include <HBBS/hbbscommon_pragmas_stc.h>
  94. #endif
  95.  
  96. #include <HBBS/Hbbsnode_protos.h>
  97. #ifdef __SASC
  98. #include <HBBS/Hbbsnode_pragmas_sas.h>
  99. #else
  100. #include <HBBS/Hbbsnode_pragmas_stc.h>
  101. #endif
  102.  
  103. long __stack=35000; // *C* how do we change this when the program is running ???
  104.  
  105. char *versionstr="$VER: Node "RELEASE_STR;
  106.  
  107.  
  108. struct Library *HBBSCommonBase=NULL;
  109. struct Library *HBBSNodeBase=NULL;
  110.  
  111. /*** global vars ***/
  112.  
  113. int gargc;
  114. char **gargv;
  115.  
  116.  
  117. // ** ALWAYS define pointers as NULL **
  118.  
  119. struct MsgPort *N_ReplyPort=NULL; // only used in GetBBSGobal so far so might define locally in that..
  120.  
  121. int N_NodeNum=-1;
  122.  
  123. char WindowTitle[50];
  124. char InfoTitle[25];
  125. char SettingsTitle[25];
  126.  
  127. char WatchUserString[80];
  128.  
  129. struct BBSGlobalData *BBSGlobal=NULL;
  130. struct NodeData *N_ND=NULL;
  131. // *C* put scr in NodeData ?
  132. struct Screen *scr;
  133. struct TextFont *HBBSFont;
  134. UWORD offx;
  135. UWORD offy;
  136. ULONG InfoWinActive=0; // callers, uploads, downloads
  137.  
  138. struct ColorSpec ScreenColors[] =
  139. {
  140. //       R     G     B
  141.    0, 0x00, 0x00, 0x00,
  142.    1, 0x0F, 0x00, 0x00,
  143.    2, 0x00, 0x0F, 0x00,
  144.    3, 0x0F, 0x0F, 0x00,
  145.    4, 0x00, 0x00, 0x0F,
  146.    5, 0x0F, 0x00, 0x0F,
  147.    6, 0x00, 0x0F, 0x0F,
  148.    7, 0x0F, 0x0F, 0x0F,
  149.   ~0, 0x00, 0x00, 0x00
  150. };
  151.  
  152. UWORD DriPens[] = {
  153.   0,7,6,1,4,6,0,0,7,0,7,4,!0 };
  154.  
  155. struct List *HistoryList;  // for Get_Line()
  156. ULONG HistoryItems=0;
  157.  
  158. ULONG rttags[] =
  159. {
  160.   RTGS_Flags, GSREQF_CENTERTEXT,
  161.   RT_Underscore, '_',
  162.   RTEZ_ReqTitle, (ULONG)"Node Message",
  163.   RT_PubScrName, NULL,  // set in main() to BBSGlobal->ScreenInfo.PubScreenName
  164.   TAG_END
  165. };
  166.  
  167. extern struct ColorSpec ScreenColors[];
  168.  
  169. #include "/common/shared.c"
  170.  
  171. void WatchScreenToFront( void )
  172. {
  173.   if (!N_ND->ConOK)
  174.   {
  175.     HBBS_OpenNodeConsoleWin();
  176.   }
  177.   if (N_ND->ConOK)
  178.   {
  179.     if (N_ND->NodeSettings.UseOwnScreen)
  180.     {
  181.       ScreenToFront(N_ND->ConScr);
  182.     }
  183.     else
  184.     {
  185.       WindowToFront(N_ND->ConWin);
  186.     }
  187.   }
  188. }
  189.  
  190. BOOL PickConScreen( void )
  191. {
  192.   BOOL retval=FALSE;
  193.   struct rtScreenModeRequester *scrmodereq;
  194.  
  195.   if (scrmodereq = rtAllocRequestA (RT_SCREENMODEREQ, NULL))
  196.   {
  197.     if (rtScreenModeRequest (scrmodereq, "Select Screen mode:",RTSC_Flags,SCREQF_GUIMODES | SCREQF_DEPTHGAD | SCREQF_SIZEGADS,
  198.                                                                RT_Window,NodeWnd,
  199.                                                                RTSC_MinHeight,200,
  200.                                                                RTSC_MinWidth,640,
  201.                                                                RTSC_MinDepth,1,
  202.                                                                RTSC_MaxDepth,3,
  203.                                                                TAG_END))
  204.     {
  205.       N_ND->NodeSettings.ScrModeID=scrmodereq->DisplayID;
  206.       N_ND->NodeSettings.ScrHeight=scrmodereq->DisplayHeight;
  207.       N_ND->NodeSettings.ScrWidth=scrmodereq->DisplayWidth;
  208.       N_ND->NodeSettings.ScrDepth=scrmodereq->DisplayDepth;
  209.       retval=TRUE;
  210.     }
  211.     rtFreeRequest(scrmodereq);
  212.   }
  213.   return(retval);
  214. }
  215.  
  216. BOOL CreateNodePorts( void )
  217. {
  218.   N_ND->ReplyPort=NULL; // set to null for FreeNodeData()...
  219.   N_ND->NodePort=NULL;
  220.   if (N_ND->OLMPort=CreateMsgPort())
  221.   {
  222.     if (N_ND->NodePort=CreatePort(N_ND->PortName,0))
  223.     {
  224.       if (N_ND->ReplyPort=CreatePort(0,0)) // don't need to be named..
  225.       {
  226.         return(TRUE);
  227.       }
  228.       else
  229.       {
  230.         DeletePort(N_ND->NodePort);
  231.         N_ND->NodePort=NULL; // set to null for FreeNodeData()...
  232.       }
  233.     }
  234.   }
  235.   return(FALSE);
  236. }
  237.  
  238. void CloseNodePorts( void )
  239. {
  240.   if (N_ND->OLMPort)
  241.   {
  242.     DeletePort(N_ND->OLMPort);
  243.     N_ND->OLMPort=NULL; // do we need ?
  244.   }
  245.   if (N_ND->NodePort)
  246.   {
  247.     DeletePort(N_ND->NodePort);
  248.     N_ND->NodePort=NULL; // do we need ?
  249.   }
  250.   if (N_ND->ReplyPort)
  251.   {
  252.     DeletePort(N_ND->ReplyPort);
  253.     N_ND->ReplyPort=NULL;
  254.   }
  255. }
  256.  
  257. void UpdateNodeWndGadgets( void )
  258. {
  259.   // must update stuff like the chat flag, user on-line, reserved etc.. etc..
  260.   GT_SetGadgetAttrs(NodeWndGadgets[NodeWnd_ChatFlag],NodeWnd,NULL,GTCY_Active,N_ND->NodeSettings.ChatFlag ? 0 : 1,TAG_DONE);
  261.   GT_SetGadgetAttrs(NodeWndGadgets[NodeWnd_Reserve],NodeWnd,NULL,GTCY_Active,N_ND->ReservedNode ? 1 : 0,TAG_DONE);
  262. }
  263.  
  264. void OpenNodeWin( struct Screen *scr )
  265. {
  266.   N_ND->NodeSettings.Iconified=TRUE; // just in case the window does not open..
  267.   if (OpenNodeWndWindow(scr)==0)
  268.   {
  269.     N_ND->NodeWnd=NodeWnd; // update node structure
  270.     offx = NodeWnd->BorderLeft;
  271.     offy = NodeWnd->BorderTop;
  272.     sprintf(WindowTitle,"HBBS Node %d Control Window! (C) "AUTHOR_SCENE,N_NodeNum);
  273.     SetWindowTitles(NodeWnd,WindowTitle,(UBYTE *) ~0);
  274.     UpdateNodeWndGadgets();
  275.     N_ND->NodeSettings.Iconified=FALSE;
  276.     DOOR_UpdateNodeStatus(UPD_NAME);
  277.     DOOR_UpdateNodeStatus(UPD_GROUP);
  278.     DOOR_UpdateNodeStatus(UPD_ACTION);
  279.     DOOR_UpdateNodeStatus(UPD_CPSBAUD);
  280.   }
  281. }
  282.  
  283. void CloseNodeWin(void)
  284. {
  285.   N_ND->NodeX=NodeWnd->LeftEdge;
  286.   N_ND->NodeY=NodeWnd->TopEdge;
  287.  
  288.   CloseNodeWndWindow();
  289.   N_ND->NodeSettings.Iconified=TRUE;
  290.   N_ND->NodeWnd=NULL; // update node structure
  291. }
  292.  
  293. /*** GUI ***/
  294.  
  295. void UpdateInfoWin( void )
  296. {
  297.   if (N_ND->InformationOpen)
  298.   {
  299.     sprintf(InfoTitle,"Info For Node %d",N_NodeNum);
  300.     SetWindowTitles(InfoWin,InfoTitle,(UBYTE *)~0);
  301.  
  302.     // update the list view..
  303.     // depending on what the user's looking at...
  304.  
  305.     switch(InfoWinActive)
  306.     {
  307.       case 0:
  308.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Callers,GTLV_Top,0,TAG_DONE);
  309.         break;
  310.       case 1:
  311.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Uploads,GTLV_Top,0,TAG_DONE);
  312.         break;
  313.       case 2:
  314.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Downloads,GTLV_Top,0,TAG_DONE);
  315.         break;
  316.       case 3:
  317.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Pagers,GTLV_Top,0,TAG_DONE);
  318.         break;
  319.       case 4:
  320.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_PWFails,GTLV_Top,0,TAG_DONE);
  321.         break;
  322.       case 5:
  323.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Carrier,GTLV_Top,0,TAG_DONE);
  324.         break;
  325.     }
  326.  
  327.     // update the calls number..
  328.     GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_Calls],InfoWin,NULL,GTNM_Number,N_ND->CallsToday,TAG_DONE);
  329.  
  330.  
  331.   }
  332. }
  333.  
  334. void ProcessWindowInfoWin( LONG Class, UWORD Code, APTR IAddress )
  335. {
  336. struct Gadget *gad;
  337. switch ( Class )
  338.   {
  339.   case IDCMP_GADGETUP :
  340.     /* Gadget message, gadget = gad. */
  341.     gad = (struct Gadget *)IAddress;
  342.     switch ( gad->GadgetID )
  343.       {
  344.       case InfoWin_LV1_Cycle1 :
  345.         /* Cycle changed   , Text of gadget :  */
  346.         InfoWinActive=Code;
  347.         UpdateInfoWin();
  348.         break;
  349.       case InfoWin_LV1 :
  350.         /* ListView pressed, Text of gadget :  */
  351.         break;
  352.       }
  353.     break;
  354.   case IDCMP_CLOSEWINDOW :
  355.     /* CloseWindow Now */
  356.     CloseInfoWinWindow();
  357.     N_ND->InformationOpen=FALSE;
  358.     break;
  359.   case IDCMP_REFRESHWINDOW :
  360.     GT_BeginRefresh( InfoWin);
  361.     /* Refresh window. */
  362.     RendWindowInfoWin( InfoWin, InfoWinVisualInfo );
  363.     GT_EndRefresh( InfoWin, TRUE);
  364.     GT_RefreshWindow( InfoWin, NULL);
  365.     RefreshGList( InfoWinGList, InfoWin, NULL, ~0);
  366.     DOOR_UpdateNodeStatus(UPD_NAME);
  367.     DOOR_UpdateNodeStatus(UPD_GROUP);
  368.     DOOR_UpdateNodeStatus(UPD_ACTION);
  369.     DOOR_UpdateNodeStatus(UPD_CPSBAUD);
  370.     break;
  371.   }
  372. }
  373.  
  374. void UpdateSettingsWindow( void )
  375. {
  376.   if (N_ND->SettingsOpen)
  377.   {
  378.     sprintf(SettingsTitle,"Settings For Node %d",N_NodeNum);
  379.     SetWindowTitles(SettingsWin,SettingsTitle,(UBYTE *)~0);
  380.  
  381.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_ModemDebug],SettingsWin,NULL,GTCB_Checked,N_ND->NodeDevice.ModemDebug,TAG_DONE);
  382.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_ModemLog],SettingsWin,NULL,GTCB_Checked,N_ND->NodeDevice.ModemLog,TAG_DONE);
  383.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_WinOrScreen],SettingsWin,NULL,GTCY_Active,N_ND->NodeSettings.UseOwnScreen ? 0 : 1,TAG_DONE);
  384.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_AllowLogins],SettingsWin,NULL,GTCY_Active,N_ND->AllowLogins ? 0 : 1,TAG_DONE);
  385.   }
  386. }
  387.  
  388. void LoadWindowSettings( void )
  389. {
  390.   struct CfgFileData *WindowCFG;
  391.   char tmpstr[BIG_STR],optionstr[10],*paramstr;
  392.   ULONG loop;
  393.   ULONG col1,col2,col3;
  394.   N_ND->ConX=0;
  395.   N_ND->ConY=11;
  396.   N_ND->ConW=640;
  397.   N_ND->ConH=200-11;
  398.  
  399.  
  400.   sprintf(tmpstr,"%sScreen.CFG",N_ND->NodeLocation);
  401.  
  402.   if (WindowCFG=HBBS_LoadConfig(tmpstr,LCFG_NONE))
  403.   {
  404.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeX,VTYPE_BIGNUM,"NodeWnd_LeftEdge",OPT_SINGLE);
  405.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeY,VTYPE_BIGNUM,"NodeWnd_TopEdge",OPT_SINGLE);
  406.  
  407.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConX,VTYPE_BIGNUM,"ConWin_LeftEdge",OPT_SINGLE);
  408.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConY,VTYPE_BIGNUM,"ConWin_TopEdge",OPT_SINGLE);
  409.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConW,VTYPE_BIGNUM,"ConWin_Width",OPT_SINGLE);
  410.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConH,VTYPE_BIGNUM,"ConWin_Height",OPT_SINGLE);
  411.  
  412.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrModeID,VTYPE_BIGNUM,OPT_NODE_ScrModeID,OPT_SINGLE);
  413.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrHeight,VTYPE_BIGNUM,OPT_NODE_ScrHeight,OPT_SINGLE);
  414.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrWidth,VTYPE_BIGNUM,OPT_NODE_ScrWidth,OPT_SINGLE);
  415.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrDepth,VTYPE_BIGNUM,OPT_NODE_ScrDepth,OPT_SINGLE);
  416.  
  417.     for (loop=0;loop<8;loop++)
  418.     {
  419.       sprintf(optionstr,"Colour_%d",loop);
  420.       paramstr=NULL;
  421.       if (HBBS_GetSetting(WindowCFG,(void *)¶mstr,VTYPE_STRING,optionstr,OPT_SINGLE))
  422.       {
  423.         if (sscanf(paramstr,"%ld %ld %ld",&col1,&col2,&col3)==3)
  424.         {
  425.           ScreenColors[loop].Red=(UWORD)col1;
  426.           ScreenColors[loop].Green=(UWORD)col2;
  427.           ScreenColors[loop].Blue=(UWORD)col3;
  428.         }
  429.         FreeStr(paramstr);
  430.       }
  431.     }
  432.  
  433.     HBBS_FlushConfig(WindowCFG);
  434.   }
  435.  
  436. }
  437.  
  438. void SaveWindowSettings( void )
  439. {
  440.   struct CfgFileData *WindowCFG;
  441.   char filename[BIG_STR],tmpstr[BIG_STR],optionstr[BIG_STR];
  442.   ULONG loop;
  443.  
  444.   sprintf(filename,"%sScreen.CFG",N_ND->NodeLocation);
  445. //  sprintf(filename,"HBBS:System/Data/Node%d_Private.CFG",N_NodeNum);
  446.  
  447.   if (WindowCFG=HBBS_CreateConfig(filename))
  448.   {
  449.     sprintf(tmpstr,"%d",NodeWnd->LeftEdge);
  450.     HBBS_AddCfgItemQuick(WindowCFG,"NodeWnd_LeftEdge",tmpstr);   // *C* make strings into variables!
  451.     sprintf(tmpstr,"%d",NodeWnd->TopEdge);
  452.     HBBS_AddCfgItemQuick(WindowCFG,"NodeWnd_TopEdge",tmpstr);
  453.  
  454.     sprintf(tmpstr,"%d",N_ND->ConWin->LeftEdge);
  455.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_LeftEdge",tmpstr);
  456.     sprintf(tmpstr,"%d",N_ND->ConWin->TopEdge);
  457.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_TopEdge",tmpstr);
  458.     sprintf(tmpstr,"%d",N_ND->ConWin->Width);
  459.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_Width",tmpstr);
  460.     sprintf(tmpstr,"%d",N_ND->ConWin->Height);
  461.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_Height",tmpstr);
  462.  
  463.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrModeID);
  464.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrModeID,tmpstr);
  465.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrHeight);
  466.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrHeight,tmpstr);
  467.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrWidth);
  468.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrWidth,tmpstr);
  469.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrDepth);
  470.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrDepth,tmpstr);
  471.  
  472.     for (loop=0;loop<8;loop++)
  473.     {
  474.       sprintf(tmpstr,"%ld %ld %ld",ScreenColors[loop].Red,ScreenColors[loop].Green,ScreenColors[loop].Blue);
  475.       sprintf(optionstr,"Colour_%d",loop);
  476.       HBBS_AddCfgItemQuick(WindowCFG,optionstr,tmpstr);
  477.     }
  478.  
  479.     if (!HBBS_SaveConfig(WindowCFG))
  480.     {
  481.       HBBS_DoErrorMessage(EMSG_CANTSAVEFILE,N_NodeNum,filename);
  482.     }
  483.     HBBS_FlushConfig(WindowCFG);
  484.   }
  485. }
  486.  
  487. void ProcessWindowSettingsWin( LONG Class, UWORD Code, APTR IAddress )
  488. {
  489. char tmpstr[1024],filename[1024];
  490. struct Gadget *gad;
  491. switch ( Class )
  492.   {
  493.   case IDCMP_GADGETUP :
  494.     /* Gadget message, gadget = gad. */
  495.     gad = (struct Gadget *)IAddress;
  496.     switch ( gad->GadgetID )
  497.       {
  498.       case SettingsWin_ScreenMode :
  499.         if (PickConScreen())
  500.         {
  501.           if (N_ND->NodeSettings.UseOwnScreen)
  502.           {
  503.             if (N_ND->ConOK) HBBS_CleanupNodeConsoleWin();
  504.             HBBS_OpenNodeConsoleWin();
  505.           }
  506.         }
  507.         break;
  508. /*
  509.       case SettingsWin_Save :
  510.         break;
  511. */
  512.       case SettingsWin_SaveWin:
  513.         SaveWindowSettings();
  514.         break;
  515.       case SettingsWin_WinOrScreen :
  516.         HBBS_ChangeConsoleMode(Code); // 0 for screen or 1 for window,2 for reverse
  517.         break;
  518.       case SettingsWin_ModemDebug :
  519.         N_ND->NodeDevice.ModemDebug=!N_ND->NodeDevice.ModemDebug;
  520.         break;
  521.       case SettingsWin_ModemLog :
  522.         N_ND->NodeDevice.ModemLog=!N_ND->NodeDevice.ModemLog;
  523.         break;
  524.       case SettingsWin_AllowLogins :
  525.         N_ND->AllowLogins=!N_ND->AllowLogins;
  526.         break;
  527.       case SettingsWin_NodeConfig :
  528.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  529.         sprintf(filename,"%sNodeLocal",N_ND->NodeLocation);
  530.         replace(tmpstr,tmpstr,"{FILE}",filename);
  531.         HBBS_RunDOSCMD(tmpstr,TRUE);
  532.         break;
  533.       case SettingsWin_CallersLog:
  534.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  535.         replace(tmpstr,tmpstr,"{FILE}",N_ND->NodeSettings.CallersLogFile);
  536.         HBBS_RunDOSCMD(tmpstr,TRUE);
  537.         break;
  538.       case SettingsWin_DeviceConfig :
  539.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  540.         sprintf(filename,"%sDevice",N_ND->NodeLocation);
  541.         replace(tmpstr,tmpstr,"{FILE}",filename);
  542.         HBBS_RunDOSCMD(tmpstr,TRUE);
  543.         break;
  544.       }
  545.     break;
  546.   case IDCMP_CLOSEWINDOW :
  547.     CloseSettingsWinWindow();
  548.     N_ND->SettingsOpen=FALSE;
  549.     // updatesettings();
  550.     break;
  551.   case IDCMP_REFRESHWINDOW :
  552.     GT_BeginRefresh( SettingsWin);
  553.     /* Refresh window. */
  554.   RendWindowSettingsWin( SettingsWin, SettingsWinVisualInfo );
  555.     GT_EndRefresh( SettingsWin, TRUE);
  556.   GT_RefreshWindow( SettingsWin, NULL);
  557.   RefreshGList( SettingsWinGList, SettingsWin, NULL, ~0);
  558.     break;
  559.   }
  560. }
  561.  
  562. void ProcessWindowNodeWnd( LONG Class, UWORD Code, APTR IAddress )
  563. {
  564. struct Gadget *gad;
  565. switch ( Class )
  566.   {
  567.   case IDCMP_GADGETUP :
  568.     /* Gadget message, gadget = gad. */
  569.     gad = (struct Gadget *)IAddress;
  570.     switch ( gad->GadgetID )
  571.       {
  572.       case NodeWnd_ChatFlag :
  573.         N_ND->NodeSettings.ChatFlag= Code == 0 ? TRUE : FALSE;
  574.         break;
  575.       case NodeWnd_OffHook :
  576.         /* Button pressed  , Text of gadget : OffHook */
  577.  
  578.         if (N_ND->OnlineStatus==OS_OFFLINE)
  579.         {
  580.           if (Code==0) // onhook...
  581.           {
  582.             InitModem();
  583.           }
  584.           if (Code==1) // off hook
  585.           {
  586.             OffHook();
  587.           }
  588.         }
  589.         else
  590.         {
  591.           if (Code==0) Code = 1; else Code=0;
  592.           // put the gadget back to what it was!
  593.           GT_SetGadgetAttrs(NodeWndGadgets[NodeWnd_OffHook],NodeWnd,NULL,GTCY_Active,Code,TAG_DONE);
  594.         }
  595.         break;
  596.       case NodeWnd_InitModem :
  597.         /* Button pressed  , Text of gadget : Init Modem */
  598.  
  599.         // only do it if no one's online..
  600.  
  601.         if (N_ND->OnlineStatus==OS_OFFLINE) InitModem();
  602.         break;
  603.       case NodeWnd_Reserve :
  604.  
  605.         N_ND->ReservedNode=!N_ND->ReservedNode;
  606.  
  607.         if (N_ND->ReservedNode)
  608.         {
  609.           if (!rtGetString (N_ND->ReservedHandle, LEN_HANDLE, "Enter user's handle to reserve the node for", NULL,RT_Window,NodeWnd, TAG_END))
  610.           {
  611.             N_ND->ReservedNode=FALSE;
  612.             UpdateNodeWndGadgets();
  613.           }
  614.         }
  615.  
  616.  
  617.         break;
  618.       case NodeWnd_Screen :
  619.         if (N_ND->ConOK)
  620.         {
  621.           HBBS_CleanupNodeConsoleWin();
  622.         }
  623.         else
  624.         {
  625.           WatchScreenToFront();
  626.         }
  627.         break;
  628.       case NodeWnd_ChatNow :
  629.         /* Button pressed  , Text of gadget : Chat Now */
  630.  
  631.         if (N_ND->OnlineStatus==OS_ONLINE)
  632.         {
  633.           // open watch window if closed and/or bring it to the front.
  634.  
  635.           WatchScreenToFront();
  636.  
  637.           if (N_ND->ConOK) // check again as if we had to open the watch window it might not have actually opened...
  638.           {
  639.             if ((N_ND->ActiveDoor==NULL) || (N_ND->ActiveDoor) && (iposition("SYSOPCHAT",N_ND->ActiveDoor->node.ln_Name)<0))
  640.             {
  641.               // only start the door if it's not already started..
  642.  
  643.               GoSystemDoor("SYSOPCHAT",NULL);
  644.             }
  645.           }
  646.         }
  647.         else DisplayBeep(scr); // Doh! Can't chat to user if no-one's logged on m8! :-)
  648.  
  649.         break;
  650.       case NodeWnd_Settings :
  651.         /* Button pressed  , Text of gadget : Settings */
  652.         if (N_ND->SettingsOpen==FALSE)
  653.         {
  654.           if (OpenSettingsWinWindow(scr)==0) // success!
  655.           {
  656.             N_ND->SettingsOpen=TRUE;
  657.             UpdateSettingsWindow();
  658.           }
  659.         }
  660.         else
  661.         {
  662.           WindowToFront(SettingsWin);
  663.         }
  664.         break;
  665.       case NodeWnd_Information :
  666.         /* Button pressed  , Text of gadget : Information */
  667.         if (N_ND->InformationOpen==FALSE)
  668.         {
  669.           if (OpenInfoWinWindow(scr)==0) // success!
  670.           {
  671.             N_ND->InformationOpen=TRUE;
  672.             UpdateInfoWin();
  673.           }
  674.         }
  675.         break;
  676.       }
  677.     break;
  678.   case IDCMP_CLOSEWINDOW :
  679.     /* CloseWindow Now */
  680.     if (N_ND->NodeSettings.Iconified==FALSE)
  681.     {
  682.       CloseNodeWin();
  683. // *R* moved to clodenodewin();
  684. //      N_ND->NodeX=N_ND->NodeWnd->LeftEdge;
  685. //      N_ND->NodeY=N_ND->NodeWnd->TopEdge;
  686.     }
  687.     break;
  688.   case IDCMP_REFRESHWINDOW :
  689.     GT_BeginRefresh( NodeWnd);
  690.     /* Refresh window. */
  691.   RendWindowNodeWnd( NodeWnd, NodeWndVisualInfo );
  692.     GT_EndRefresh( NodeWnd, TRUE);
  693.   GT_RefreshWindow( NodeWnd, NULL);
  694.   RefreshGList( NodeWndGList, NodeWnd, NULL, ~0);
  695.     break;
  696.   case IDCMP_VANILLAKEY :
  697.     /* Processed key press */
  698.     /* gadgets need processing perhaps. */
  699.     break;
  700.   }
  701. }
  702.  
  703. void ProcessConWindow( LONG Class, UWORD Code, APTR IAddress )
  704. {
  705. //  struct Gadget *gad;
  706.  
  707.   switch ( Class )
  708.   {
  709.     case IDCMP_CLOSEWINDOW :
  710.       /* CloseWindow Now */
  711.  
  712.       // get thesetings for the window position now so that it will open in the same place
  713.       HBBS_CleanupNodeConsoleWin();
  714.       break;
  715.     case IDCMP_REFRESHWINDOW :
  716.       GT_BeginRefresh( NodeWnd);
  717.       /* Refresh window. */
  718.       RendWindowNodeWnd( NodeWnd, NodeWndVisualInfo );
  719.       GT_EndRefresh( NodeWnd, TRUE);
  720.       GT_RefreshWindow( NodeWnd, NULL);
  721.       RefreshGList( NodeWndGList, NodeWnd, NULL, ~0);
  722.       break;
  723.   }
  724. }
  725.  
  726. void SendStatus(V_BIGNUM status)
  727. {
  728.   struct StatusMsg *SMsg;
  729.  
  730.   if (SMsg=(struct StatusMsg *)AllocVec(sizeof(struct StatusMsg),MEMF_PUBLIC))
  731.   {
  732.     SMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  733.     SMsg->message.mn_ReplyPort=NULL;//N_ND->ReplyPort;
  734.     SMsg->message.mn_Length=sizeof(struct StatusMsg);
  735.     SMsg->MsgType=mtype_STATUS;
  736.     SMsg->NodeNum=N_ND->NodeNum;
  737.     SMsg->Status=status;
  738.     SendMessage((struct Message*)SMsg,CtrlMainPortName);
  739.   }
  740. }
  741.  
  742. void SendRequest(V_BIGNUM requesttype)
  743. {
  744.   struct RequestMsg *RMsg;
  745.  
  746.   if (RMsg=(struct RequestMsg *)AllocVec(sizeof(struct RequestMsg),MEMF_PUBLIC))
  747.   {
  748.     RMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  749.     RMsg->message.mn_ReplyPort=NULL;//N_ND->ReplyPort;
  750.     RMsg->message.mn_Length=sizeof(struct RequestMsg);
  751.     RMsg->MsgType=mtype_REQUEST;
  752.     RMsg->NodeNum=N_ND->NodeNum;
  753.     RMsg->Flags=requesttype;
  754.     SendMessage((struct Message*)RMsg,CtrlMainPortName);
  755.   }
  756. }
  757.  
  758.  
  759. void ClearDeviceData(struct DeviceData *DD)
  760. {
  761.   // small subroutine to set all the default values
  762.   // never call if you've allocated mem for strings!
  763.   DD->DeviceName=NULL;
  764.   DD->SerialDevice=NULL;
  765.   DD->SerialUnit=0;
  766.   DD->SerialBaud=0;
  767.   DD->NullModemCable=FALSE;
  768.   DD->ModemDebug=FALSE;
  769.   DD->ModemLog=FALSE;
  770.   DD->EchoRetries=0;
  771.   DD->ReOpenRetries=0;
  772.   DD->ReOpenDelay=0;
  773.   DD->LockUpScript=NULL;
  774.   DD->MaxCommandWait=0;
  775.   DD->CommandRetries=0;
  776.   DD->DelayBetweenCmds=0;
  777.   DD->TildeDelay=0;
  778.   DD->TurnOnEcho=NULL;
  779.   DD->TurnOnEchoDelay=0;
  780.   DD->ModemInit=NULL;
  781.   DD->StrictConnect=FALSE;
  782.   DD->StrictConnectStr=NULL;
  783.   DD->RelaxedConnectStr=NULL;
  784.   DD->CommandModeString=NULL;
  785.   DD->DropDTRHangup=FALSE;
  786.   DD->HangUpString=NULL;
  787.   DD->OffHookString=NULL;
  788.   DD->Incoming=NULL;
  789.   DD->ImmediateAnswer=NULL;
  790.   DD->DumpModem=FALSE;
  791.   DD->UseCRLF=FALSE;
  792. }
  793.  
  794. void SetDeviceDataDefaults(struct DeviceData *DD)
  795. {
  796.   // small subroutine to set all the default values
  797.  
  798.   DD->EchoRetries=4;
  799.   DD->ReOpenRetries=2;
  800.   DD->ReOpenDelay=25;
  801.   DD->MaxCommandWait=10;
  802.   DD->CommandRetries=3;
  803.   DD->DelayBetweenCmds=1;
  804.   DD->TildeDelay=22;
  805.   DD->TurnOnEchoDelay=20;
  806.   DD->DropDTRHangup=TRUE;
  807. }
  808.  
  809. void FreeDeviceData(struct DeviceData *DD)
  810. {
  811.   FreeStr(DD->DeviceName);
  812.   FreeStr(DD->SerialDevice);
  813.   FreeStr(DD->LockUpScript);
  814.   FreeStr(DD->HangUpString);
  815.   FreeStr(DD->OffHookString);
  816.   FreeStr(DD->Incoming);
  817.   FreeStr(DD->ImmediateAnswer);
  818.   FreeStrList(DD->TurnOnEcho);
  819.   FreeStrList(DD->ModemInit);
  820.   FreeStrList(DD->StrictConnectStr);
  821.   FreeStrList(DD->CommandModeString);
  822.   FreeStrList(DD->RelaxedConnectStr);
  823. }
  824.  
  825. V_ERROR LoadDeviceData(ULONG NodeNum,struct DeviceData *DD )
  826. {
  827.   struct CfgFileData *DeviceCFG;
  828.   V_ERROR error=TYPE_NONE;
  829.   UBYTE ecode=0;
  830.   UBYTE *filename=NULL;
  831.   struct NodeData *ND;
  832.  
  833.   if (ND=HBBS_NodeDataPtr(NodeNum))
  834.   {
  835.     if (filename=AllocVec(strlen(ND->NodeLocation)+strlen(FILENAME_DEVICE)+1,MEMF_PUBLIC))
  836.     {
  837.       strcpy(filename,ND->NodeLocation);
  838.       strcat(filename,FILENAME_DEVICE);
  839.     }
  840.   }
  841.  
  842.   if (filename)
  843.   {
  844.     if (DeviceCFG=HBBS_LoadConfig(filename,LCFG_NONE))
  845.     {
  846.       // get settings!
  847.  
  848.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->DeviceName       ,VTYPE_STRING,OPT_DEVICE_DeviceName       ,OPT_SINGLE)) ecode=1;
  849.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->SerialDevice     ,VTYPE_STRING,OPT_DEVICE_SerialDevice     ,OPT_SINGLE)) ecode=2;
  850.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->SerialUnit       ,VTYPE_BIGNUM,OPT_DEVICE_SerialUnit       ,OPT_SINGLE)) ecode=3;
  851.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->SerialBaud       ,VTYPE_BIGNUM,OPT_DEVICE_SerialBaud       ,OPT_SINGLE)) ecode=4;
  852.       /*if (!*/HBBS_GetSetting(DeviceCFG,(void *)&DD->NullModemCable   ,VTYPE_BOOL,OPT_DEVICE_NullModemCable     ,OPT_SINGLE);/*) ecode=5;*/
  853.       if (!DD->NullModemCable)
  854.       {
  855.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ModemDebug       ,VTYPE_BOOL,OPT_DEVICE_ModemDebug         ,OPT_SINGLE)) ecode=6;
  856.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ModemLog         ,VTYPE_BOOL,OPT_DEVICE_ModemLog           ,OPT_SINGLE)) ecode=7;
  857.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->EchoRetries      ,VTYPE_SMALLNUM,OPT_DEVICE_EchoRetries    ,OPT_SINGLE)) ecode=8;
  858.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ReOpenRetries    ,VTYPE_SMALLNUM,OPT_DEVICE_ReOpenRetries  ,OPT_SINGLE)) ecode=9;
  859.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ReOpenDelay      ,VTYPE_TIME,OPT_DEVICE_ReOpenDelay        ,OPT_SINGLE)) ecode=10;
  860.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->LockUpScript     ,VTYPE_STRING,OPT_DEVICE_LockUpScript     ,OPT_SINGLE)) ecode=11;
  861.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->MaxCommandWait   ,VTYPE_TIME,OPT_DEVICE_MaxCommandWait     ,OPT_SINGLE)) ecode=12;
  862.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->CommandRetries   ,VTYPE_SMALLNUM,OPT_DEVICE_CommandRetries ,OPT_SINGLE)) ecode=13;
  863.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->DelayBetweenCmds ,VTYPE_TIME,OPT_DEVICE_DelayBetweenCmds   ,OPT_SINGLE)) ecode=14;
  864.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->TildeDelay       ,VTYPE_TIME,OPT_DEVICE_TildeDelay         ,OPT_SINGLE)) ecode=15;
  865.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->TurnOnEcho       ,VTYPE_STRINGLIST,OPT_DEVICE_TurnOnEcho   ,OPT_MULTI)) ecode=16;
  866.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->TurnOnEchoDelay  ,VTYPE_BIGNUM,OPT_DEVICE_TurnOnEchoDelay  ,OPT_SINGLE)) ecode=17;
  867.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ModemInit        ,VTYPE_STRINGLIST,OPT_DEVICE_ModemInit    ,OPT_MULTI)) ecode=18;
  868.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->StrictConnect    ,VTYPE_BOOL,OPT_DEVICE_StrictConnect      ,OPT_SINGLE)) ecode=19;
  869.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->StrictConnectStr ,VTYPE_STRINGLIST,OPT_DEVICE_StrictConnectStr ,OPT_MULTI) && DD->StrictConnect) ecode=20;
  870.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->RelaxedConnectStr,VTYPE_STRINGLIST,OPT_DEVICE_RelaxedConnectStr,OPT_MULTI) && !DD->StrictConnect) ecode=21;
  871.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->DropDTRHangup    ,VTYPE_BOOL,OPT_DEVICE_DropDTRHangup      ,OPT_SINGLE)) ecode=22;
  872.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->CommandModeString,VTYPE_STRINGLIST,OPT_DEVICE_CommandModeString,OPT_MULTI)) ecode=23;
  873.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->HangUpString     ,VTYPE_STRING,OPT_DEVICE_HangUpString     ,OPT_SINGLE)) ecode=24;
  874.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->OffHookString    ,VTYPE_STRING,OPT_DEVICE_OffHookString    ,OPT_SINGLE)) ecode=25;
  875.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->Incoming         ,VTYPE_STRING,OPT_DEVICE_Incoming         ,OPT_SINGLE)) ecode=26;
  876.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ImmediateAnswer  ,VTYPE_STRING,OPT_DEVICE_ImmediateAnswer  ,OPT_SINGLE)) ecode=27;
  877.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->DumpModem        ,VTYPE_BOOL,OPT_DEVICE_DumpModem          ,OPT_SINGLE)) ecode=28;
  878.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->UseCRLF          ,VTYPE_BOOL,OPT_DEVICE_UseCRLF            ,OPT_SINGLE)) ecode=29;
  879.       }
  880.  
  881.       if (ecode>0)
  882.       {
  883.         error=TYPE_FATAL;
  884.         HBBS_DoErrorMessage(EMSG_DEVICECFG+ecode-1,N_NodeNum,filename);
  885.       }
  886.       HBBS_FlushConfig(DeviceCFG);
  887.       DD->SysopNode=FALSE;
  888.     }
  889.     else
  890.     {
  891.       DD->SysopNode=TRUE;
  892.     }
  893.     FreeVec(filename);
  894.   }
  895.   return(error);
  896. }
  897.  
  898.  
  899. static VOID cleanup(ULONG num)
  900. {
  901.   if (HBBSNodeBase)
  902.   {
  903.     HBBS_CleanUpNode();
  904.     CloseLibrary (HBBSNodeBase);
  905.   }
  906.  
  907.   if (HBBSCommonBase)
  908.   {
  909.     HBBS_CleanUpCommon();
  910.     CloseLibrary (HBBSCommonBase);
  911.   }
  912.  
  913.   if (N_ReplyPort)
  914.     DeleteMsgPort(N_ReplyPort);
  915.  
  916.   if (num)
  917.   {
  918.     HBBS_DoErrorMessage(num,N_NodeNum,NULL);
  919.   }
  920.  
  921.   if (ReqToolsBase)
  922.     CloseLibrary ((struct Library *)ReqToolsBase);
  923.  
  924.   exit(0);
  925. }
  926.  
  927. static VOID init(VOID)
  928. {
  929.   if (!(ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
  930.   {
  931.     cleanup(EMSG_NOREQTOOLS);
  932.   }
  933.  
  934.   if (!(N_ReplyPort=CreateMsgPort()))
  935.   {
  936.     cleanup(EMSG_NOMEM);
  937.   }
  938.  
  939.   if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  940.   {
  941.     cleanup(EMSG_NOCOMMON);
  942.   }
  943.  
  944.   if (!(HBBS_InitCommon()))
  945.   {
  946.     cleanup(EMSG_COMMONERR);
  947.   }
  948.  
  949.   if(!(HBBSNodeBase = OpenLibrary("HBBSNode.library",0)))
  950.   {
  951.     cleanup(EMSG_NONODE);
  952.   }
  953.  
  954.   if (!(HBBS_InitNode(N_NodeNum)))
  955.   {
  956.     cleanup(EMSG_NODEERR);
  957.   }
  958. }
  959.  
  960. /*
  961. V_ERROR GetBBSGlobal(void)
  962. {
  963.   struct AskMsg *AMsg,*Reply;
  964.   V_ERROR error=TYPE_CRITICAL;
  965.  
  966.   if (AMsg=(struct AskMsg *)AllocVec(sizeof(struct AskMsg),MEMF_PUBLIC))
  967.   {
  968.     // create the message
  969.     AMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  970.     AMsg->message.mn_ReplyPort=N_ReplyPort;
  971.     AMsg->message.mn_Length=sizeof(struct AskMsg);
  972.     AMsg->MsgType=mtype_ASK; // so CONTROL knows what type of message structe to typecast to..
  973.     AMsg->NodeNum=N_NodeNum; // can't use N_ND->NodeNum yet.. as we don't know N_ND
  974.     AMsg->Flags=ASK_BBSGLOBAL;
  975.  
  976.     // now send it to ctrlmain, note we can't use N_ND->ReplyPort as we don't know N_ND yet!!
  977.  
  978.     if (SafePutToPort((struct Message *)AMsg,CtrlMainPortName))
  979.     {
  980.       if (1L << N_ReplyPort->mp_SigBit==Wait(1L << N_ReplyPort->mp_SigBit))
  981.       {
  982.         Reply=(struct AskMsg*)GetMsg(N_ReplyPort);
  983.         if (Reply)
  984.         {
  985.           BBSGlobal=(struct BBSGlobalData *)Reply->Pointer;
  986.           error=TYPE_NONE;
  987.         }
  988.       }
  989.     }
  990.     FreeVec(AMsg);
  991.   }
  992.   return(error);
  993. }
  994. */
  995.  
  996. V_ERROR CheckNodePath(char *str)
  997. {
  998.   V_ERROR error=TYPE_NONE;
  999.  
  1000.   if (!PathOK(str))
  1001.   {
  1002.     HBBS_DoErrorMessage(EMSG_NODEDIRMISSING,N_ND->NodeNum,str);
  1003.     error=TYPE_CRITICAL;
  1004.   }
  1005.   return (error);
  1006. }
  1007.  
  1008. V_ERROR CheckNodePaths( void )
  1009. {
  1010.   V_BIGNUM errors=0;
  1011.   char tmpstr[BIG_STR];
  1012.  
  1013.  
  1014.   if (CheckNodePath(N_ND->NodeSettings.NodePlayPen)!=TYPE_NONE) errors++;
  1015.  
  1016.   strcpy(tmpstr,N_ND->NodeLocation);
  1017.   strcat(tmpstr,"Commands");
  1018.   if (CheckNodePath(tmpstr)!=TYPE_NONE) errors++;
  1019.  
  1020.   strcpy(tmpstr,N_ND->NodeLocation);
  1021.   strcat(tmpstr,"Work");
  1022.   if (CheckNodePath(tmpstr)!=TYPE_NONE) errors++;
  1023.  
  1024.   strcpy(tmpstr,N_ND->NodeLocation);
  1025.   strcat(tmpstr,"Screens");
  1026.   if (CheckNodePath(tmpstr)!=TYPE_NONE) errors++;
  1027.  
  1028.   return (errors >0 ? (ULONG)TYPE_CRITICAL : (ULONG)TYPE_NONE);
  1029. }
  1030.  
  1031. V_BOOL InitNode(void)
  1032. {
  1033.   int loop;
  1034.   struct Node *node;
  1035.   V_BOOL error=FALSE;
  1036.   UBYTE ecode=0;
  1037.   // *C* add error messages and return codes here ?
  1038.   if (!CreateNodePorts())
  1039.   {
  1040.     ecode=1;
  1041.   }
  1042.   else
  1043.   {
  1044.     // ports must be created before sendstatus will work..
  1045.     SendStatus(STAT_INITIALIZING);
  1046.     ecode=2;
  1047.     if (N_ND->BBSCols=(struct BBSColsData*)AllocVec(sizeof(struct BBSColsData),MEMF_CLEAR|MEMF_PUBLIC))
  1048.     {
  1049.       if (N_ND->BBSStrings=(struct BBSStringsData*)AllocVec(sizeof(struct BBSStringsData),MEMF_CLEAR|MEMF_PUBLIC))
  1050.       {
  1051.         if (N_ND->OLMList=HBBS_CreateList())
  1052.         {
  1053.           N_ND->User.ConfAcs.Name=NULL;
  1054.           N_ND->OLMCount=0;
  1055.           if (N_ND->Last_Callers=HBBS_CreateList())
  1056.           {
  1057.             if (N_ND->Last_Uploads=HBBS_CreateList())
  1058.             {
  1059.               if (N_ND->Last_Downloads=HBBS_CreateList())
  1060.               {
  1061.                 if (N_ND->Last_PWFails=HBBS_CreateList())
  1062.                 {
  1063.                   if (N_ND->Last_Carrier=HBBS_CreateList())
  1064.                   {
  1065.                     if (N_ND->Last_Pagers=HBBS_CreateList())
  1066.                     {
  1067.                       if (N_ND->User.ConfAcs.See=HBBS_CreateList())
  1068.                       {
  1069.                         for (loop=0;(!error) && (loop<BBSGlobal->Conferences);loop++)
  1070.                         {
  1071.                           if (node=AllocVec(sizeof(struct BoolNode),MEMF_CLEAR|MEMF_PUBLIC))
  1072.                           {
  1073.                             AddTail(N_ND->User.ConfAcs.See,node);
  1074.                           }
  1075.                           else error=TRUE;
  1076.                         }
  1077.                         if (!error)
  1078.                         {
  1079.                           if (N_ND->User.ConfAcs.Access=HBBS_CreateList())
  1080.                           {
  1081.                             for (loop=0;(!error) && (loop<BBSGlobal->Conferences);loop++)
  1082.                             {
  1083.                               if (node=AllocVec(sizeof(struct BoolNode),MEMF_CLEAR|MEMF_PUBLIC))
  1084.                               {
  1085.                                 AddTail(N_ND->User.ConfAcs.Access,node);
  1086.                               }
  1087.                               else error=TRUE;
  1088.                             }
  1089.                             if (!error)
  1090.                             {
  1091.  
  1092.                               N_ND->HBBSFont=HBBSFont;
  1093.                               N_ND->HBBSTextAttr=&HBBS8066;
  1094.                               N_ND->ScrCols=&ScreenColors[0];
  1095.                               N_ND->DriPens=&DriPens[0];
  1096.                               ecode=0;
  1097.                               ClearNodeData(&N_ND->NodeSettings);
  1098.                               ClearDeviceData(&N_ND->NodeDevice);
  1099.                               SetDeviceDataDefaults(&N_ND->NodeDevice);
  1100.                               CopyNodeSettings(&N_ND->NodeSettings,&BBSGlobal->NodeGlobalData->NodeSettings);
  1101.                               N_ND->NodeFlags=NFLG_NONE;
  1102.                               if (LoadNodeSettingsData(N_NodeNum,&N_ND->NodeSettings)==TYPE_NONE)
  1103.                               {
  1104.                                 if (CheckNodePaths()==TYPE_NONE)
  1105.                                 {
  1106.                                   HBBS_SetBBSCols();
  1107.                                   if (N_ND->NodeTimer=InitTimer())
  1108.                                   {
  1109.                                     if (N_ND->NodeSettings.UseDevice)
  1110.                                     {
  1111.                                       if (LoadDeviceData(N_NodeNum,&N_ND->NodeDevice)==TYPE_NONE)
  1112.                                       {
  1113.                                         if (OpenSerial())
  1114.                                         {
  1115.                                           return(TRUE);
  1116.                                         }
  1117.                                       } else ecode=3; //HBBS_DoErrorMessage(EMSG_DEVICEFILEERR,N_ND->NodeNum,NULL);
  1118.                                     }
  1119.                                     else
  1120.                                     {
  1121.                                       return(TRUE);
  1122.                                     }
  1123.                                   } else ecode=4; //HBBS_DoErrorMessage(EMSG_NOTIMER,N_ND->NodeNum,NULL);
  1124.                                 }
  1125.                               } else HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_NODESETTINGS,NULL,TYPE_FATAL);
  1126.                             }
  1127.                           }
  1128.                         }
  1129.                       }
  1130.                     }
  1131.                   }
  1132.                 }
  1133.               }
  1134.             }
  1135.           }
  1136.         }
  1137.       }
  1138.     }
  1139.     SendStatus(STAT_CLOSED);
  1140.   }
  1141.   if (ecode) HBBS_DoErrorMessage(EMSG_NODEINIT+ecode-1,N_NodeNum,NULL);
  1142.   return(FALSE);
  1143. }
  1144.  
  1145. void FreeNode( void )
  1146. {
  1147.   SendStatus(STAT_CLOSING);
  1148.   if (N_ND->NodeTimer) CleanupTimer(N_ND->NodeTimer);
  1149.   FreeStrList(N_ND->Last_Callers);
  1150.   FreeStrList(N_ND->Last_Uploads);
  1151.   FreeStrList(N_ND->Last_Downloads);
  1152.   FreeStrList(N_ND->Last_Pagers);
  1153.   FreeStrList(N_ND->Last_PWFails);
  1154.   FreeStrList(N_ND->Last_Carrier);
  1155.   FreeStrList(N_ND->OLMList);
  1156.   N_ND->OLMList=NULL; //must be done!!
  1157.  
  1158.   FreeStrList(N_ND->User.ConfAcs.See);
  1159.   FreeStrList(N_ND->User.ConfAcs.Access);
  1160.   FreeStr(N_ND->User.ConfAcs.Name);
  1161.  
  1162.   if (N_ND->BBSCols)
  1163.   {
  1164.     FreeVec(N_ND->BBSCols->MenuTextANSI);
  1165.     FreeVec(N_ND->BBSCols->MenuOpenBracket);
  1166.     FreeVec(N_ND->BBSCols->MenuCloseBracket);
  1167.     FreeVec(N_ND->BBSCols->MenuHighlightANSI);
  1168.     FreeVec(N_ND->BBSCols->MenuDefaultOptANSI);
  1169.     FreeVec(N_ND->BBSCols->MenuPromptANSI);
  1170.     FreeVec(N_ND->BBSCols);
  1171.   }
  1172.   FreeDeviceData(&N_ND->NodeDevice);
  1173.   FreeNodeSettingsData(&N_ND->NodeSettings);
  1174.   SendStatus(STAT_CLOSED);
  1175.   // must be done last cos status won't work otherwise..
  1176.   CloseNodePorts();
  1177.   HBBS_ResetNodeData(N_ND);
  1178. }
  1179.  
  1180. /*
  1181. void HandleAsk(struct AskMsg *AMsg)
  1182. {
  1183.   switch(AMsg->Flags)
  1184.   {
  1185.     case ASK_STATUS:
  1186.       AMsg->Value=N_ND->Status;
  1187.       break;
  1188.   }
  1189.   ReplyMsg((struct Message *)AMsg);
  1190. }
  1191. */
  1192.  
  1193. // returns 1 if quit..
  1194. void HandleStatus(struct StatusMsg *SMsg)
  1195. {
  1196.   switch(SMsg->Status)
  1197.   {
  1198.     case STAT_REQUESTCLOSE:
  1199.       // node must NOT be doing anything if we want to shut it down
  1200.       if (N_ND->Status==STAT_READY) N_ND->RequestShutdown=TRUE;
  1201.       break;
  1202.  
  1203.     case STAT_OPENWINDOW:
  1204.       if (N_ND->NodeSettings.Iconified==TRUE)
  1205.       {
  1206.         OpenNodeWin(scr);
  1207.       }
  1208.       break;
  1209.     case STAT_CLOSEWINDOW:
  1210.       // *C* change to abort con if window closed pressed as we can't actually
  1211.       // care about the console coming in if we're closing the window!
  1212.       // ah, but what if a door does care ??? Umm.. fuck it.. who cares it's staying
  1213.       if (N_ND->NodeSettings.Iconified==FALSE && N_ND->ConWaiting==FALSE)
  1214.       {
  1215.         CloseNodeWin();
  1216.       }
  1217.       break;
  1218.     case STAT_OPENSCREEN:
  1219.       WatchScreenToFront();
  1220.       break;
  1221.     case STAT_CLOSESCREEN:
  1222.       if (N_ND->ConOK==TRUE)
  1223.       {
  1224.         HBBS_CleanupNodeConsoleWin();
  1225.       }
  1226.       break;
  1227.   }
  1228.  
  1229.   // a status message MAY be sent to the node without the control or other program wanting to be told
  1230.   // that the NODE has recived the message, all messages sent that DONT want a reply WILL be freed..
  1231.  
  1232.   if (SMsg->message.mn_ReplyPort)
  1233.   {
  1234.     ReplyMsg((struct Message *)SMsg);
  1235.   }
  1236.   else
  1237.   {
  1238.     FreeVec(SMsg);
  1239.   }
  1240. }
  1241.  
  1242. void HandleDoorActivityMsg(struct DoorActivityMsg *DMsg) // *C* whatr's this used for now ??
  1243. {
  1244.   switch(DMsg->Status)
  1245.   {
  1246.     case DMSG_DOORSTARTED:
  1247. //      printf("Door Started! (%s)\n",N_ND->ActiveDoor->node.ln_Name);
  1248.       break;
  1249.     case DMSG_DOORFINISHED:
  1250. //      printf("Door Finished!\n");
  1251.       break;
  1252.   }
  1253.   // a door message MAY be sent to the node without the control or other program wanting to be told
  1254.   // that the NODE has recived the message, all messages sent that DONT want a reply WILL be freed..
  1255.  
  1256.   if (DMsg->message.mn_ReplyPort)
  1257.   {
  1258.     ReplyMsg((struct Message *)DMsg);
  1259.   }
  1260.   else
  1261.   {
  1262.     FreeVec(DMsg);
  1263.   }
  1264. }
  1265.  
  1266. void HandleCheckMsg(struct NodeMsg *NMsg)  // *R* needed ?
  1267. {
  1268.   if (NMsg->message.mn_ReplyPort)
  1269.   {
  1270.     ReplyMsg((struct Message *)NMsg);
  1271.   }
  1272.   else
  1273.   {
  1274.     FreeVec(NMsg);
  1275.   }
  1276. }
  1277.  
  1278. void HandleMsg( void )
  1279. {
  1280.   struct NodeMsg *NMsg;
  1281.  
  1282.  
  1283.   while (NMsg=(struct NodeMsg*)GetMsg(N_ND->NodePort))
  1284.   {
  1285.     if ( (NMsg->MsgType==mtype_DOORIO) && ( ((struct DoorIOMsg *)NMsg)->Status==DOORIO_WRITESTR ) )
  1286.     {
  1287.       if (((struct DoorIOMsg *)NMsg)->Data)
  1288.       {
  1289.         if (N_ND->ConOK)
  1290.         {
  1291.           N_ND->ConWrite->io_Command  = CMD_WRITE;
  1292.           N_ND->ConWrite->io_Data     = ((struct DoorIOMsg *)NMsg)->Data;
  1293.           N_ND->ConWrite->io_Length   = -1;
  1294.           DoIO((struct IORequest *)N_ND->ConWrite);
  1295.         }
  1296.         if ((N_ND->LoginType==LOGIN_REMOTE) && (!(N_ND->NodeFlags & NFLG_BLOCKSERIAL)))
  1297.         {
  1298.           AbortSerRead();
  1299.           N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  1300.           N_ND->SerWrite->IOSer.io_Data     = ((struct DoorIOMsg *)NMsg)->Data;
  1301.           N_ND->SerWrite->IOSer.io_Length   = -1;
  1302.           DoIO((struct IORequest *)N_ND->SerWrite);
  1303.         }
  1304.       }
  1305.       ReplyMsg((struct Message *)NMsg);
  1306.     }
  1307.     else
  1308.     {
  1309.       switch(NMsg->MsgType)
  1310.       {
  1311. //        case mtype_ASK:
  1312. //          HandleAsk((struct AskMsg *)NMsg);
  1313. //          break;
  1314.         case mtype_STATUS:
  1315.           HandleStatus((struct StatusMsg *)NMsg);
  1316.           break;
  1317.         case mtype_DOORACTIVITY:
  1318.           HandleDoorActivityMsg((struct DoorActivityMsg *)NMsg);
  1319.           break;
  1320.         case mtype_DOORIO:
  1321.           HandleDoorIOMsg((struct DoorIOMsg *)NMsg);
  1322.           break;
  1323.         case mtype_CHECK:   // all we want to do is get the node to check some stuff
  1324.           HandleCheckMsg(NMsg); // depending on what it's doing...
  1325.           break;
  1326.       }
  1327.     }
  1328.     // we might get a message that does not want a reply.. (like a request shutdown message..)
  1329.   }
  1330. }
  1331.  
  1332. // copied and modified from NodeGUI.c as the version in there does NOT free the fonts!!!!
  1333.  
  1334. int OpenTheDiskFonts( void )
  1335. {
  1336.   int OKSoFar = 1; // reveresed numbers
  1337.   if ((HBBSFont = OpenDiskFont( &HBBS8066 ))==NULL )
  1338.   OKSoFar = 0;
  1339. return ( OKSoFar );
  1340. }
  1341.  
  1342. void NodeMain(void)
  1343. {
  1344.   char outstr[40];
  1345.  
  1346.   if (OpenLibs()==0)
  1347.   {
  1348.     sprintf(outstr,"Starting Node %d",N_ND->NodeNum);
  1349.     HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_DONTCARE);
  1350.  
  1351.     if (OpenTheDiskFonts())
  1352.     {
  1353.       if (scr=LockPubScreen(BBSGlobal->ScreenInfo.PubScreenName))
  1354.       {
  1355.         if (InitNode())
  1356.         {
  1357.           SendStatus(STAT_READY);
  1358.           HBBS_LoadCallsData();
  1359.           LoadWindowSettings();
  1360.           if (N_ND->NodeSettings.Iconified==FALSE) OpenNodeWin(scr);
  1361.           if (N_ND->NodeSettings.StartScreen) HBBS_OpenNodeConsoleWin();
  1362.  
  1363.           sprintf(outstr,"Node %d Started OK",N_ND->NodeNum);
  1364.           HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_DONTCARE);
  1365.  
  1366.           AwaitConnect();
  1367.  
  1368.           if (N_ND->NodeSettings.Iconified==FALSE) CloseNodeWin();
  1369.           if (N_ND->SettingsOpen) CloseSettingsWinWindow();
  1370.           if (N_ND->InformationOpen) CloseInfoWinWindow();
  1371.           if (N_ND->ConOK) HBBS_CleanupNodeConsoleWin();
  1372.           if (N_ND->SerOK) CleanupSerial();
  1373.         }
  1374.         FreeNode();
  1375.         UnlockPubScreen(NULL, scr);
  1376.       } else HBBS_DoErrorMessage(EMSG_NOSCREEN,0,NULL);
  1377.       sprintf(outstr,"Node %d Stopped",N_ND->NodeNum);
  1378.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_DONTCARE);
  1379.       CloseFont( HBBSFont ) ;
  1380.     }
  1381.     else  HBBS_DoErrorMessage(EMSG_NOFONT,0,NULL);
  1382.     CloseLibs();
  1383.   } else HBBS_DoErrorMessage(EMSG_NOLIBS,0,NULL);
  1384. }
  1385.  
  1386. int main(int argc,char *argv[])
  1387. {
  1388.   struct MsgPort *tmpport;
  1389.   char tmpstr[20];
  1390.  
  1391.   gargc=argc;
  1392.   gargv=argv;
  1393.  
  1394.   if ((argc<2) || (sscanf(argv[1],"%d",&N_NodeNum)==0))
  1395.   {
  1396.     printf("Invalid/No Paramaters for node!\n");
  1397.     exit (20);
  1398.   }
  1399.   sprintf(tmpstr,"HBBS_Node %d",N_NodeNum);
  1400.   SetProgramName(tmpstr);
  1401.   init();
  1402.   if (BBSGlobal=HBBS_GimmeBBS())
  1403.   {
  1404.     rttags[7]=(ULONG)BBSGlobal->ScreenInfo.PubScreenName;
  1405.     if (N_NodeNum >= BBSGlobal->BBSNodes)
  1406.     {
  1407.       HBBS_DoErrorMessage(EMSG_NODEINVALID,N_NodeNum,NULL);
  1408.     }
  1409.     else
  1410.     {
  1411.       if (N_ND=HBBS_NodeDataPtr(N_NodeNum)) // this should not fail in normal circumstances..
  1412.       {
  1413.         Forbid();
  1414.         tmpport=FindPort(N_ND->PortName);
  1415.         Permit();
  1416.         if (tmpport)
  1417.         {
  1418.           HBBS_DoErrorMessage(EMSG_NODEALREADYUP,N_NodeNum,NULL);
  1419.         }
  1420.         else
  1421.         {
  1422.           // actually already set by control..
  1423.           //N_ND->NodeNum=N_NodeNum; // set the node number (as gained from command line params)
  1424.           NodeMain();
  1425.         }
  1426.       }
  1427.     }
  1428.   } else HBBS_DoErrorMessage(EMSG_NOCTRL,0,NULL);
  1429.   cleanup(0);
  1430. }
  1431.